package com.jagochan.module.rbac.config.satoken;

import cn.dev33.satoken.stp.StpInterface;
import com.jagochan.module.rbac.common.Constants;
import com.jagochan.module.rbac.common.exception.BusinessException;
import com.jagochan.module.rbac.sys_menu.domain.SysMenu;
import com.jagochan.module.rbac.sys_menu.service.SysMenuService;
import com.jagochan.module.rbac.sys_user.domain.SysUser;
import com.jagochan.module.rbac.sys_user.service.SysUserService;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Component;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * Sa-Token 将从此实现类获取每个账号拥有的权限码
 */
@RequiredArgsConstructor
@Component
public class StpInterfaceImp implements StpInterface {
    private final SysUserService sysUserService;
    private final SysMenuService sysMenuService;

    /**
     * 返回一个账号所拥有的权限码集合
     *
     * @param loginId   账号id，即你在调用 StpUtil.login(id) 时写入的标识值
     * @param loginType 账号体系标识
     * @return 一个账号所拥有的权限码集合
     */
    @Override
    public List<String> getPermissionList(Object loginId, String loginType) {
        // 1. 根据id查询用户信息
        SysUser user = sysUserService.getById((Serializable) loginId);

        // 2. 查询当前用户拥有的菜单列表
        List<SysMenu> menuList;
        // 判断是否是超级管理员
        if (StringUtils.isNotEmpty(user.getIsAdmin()) && Constants.IS_ADMIN.equals(user.getIsAdmin())) {
            // 超级管理员, 查询全部菜单
            // menuList = sysMenuService.list();
            return List.of("*"); // 超级管理员拥有全部权限
        } else {
            menuList = sysMenuService.listMenuByUserId(user.getUserId() + "");
        }
        if (menuList.stream().noneMatch(Objects::nonNull)) {
            throw new BusinessException(500, "该用户对应的角色未分配菜单权限，请用管理员账号登录分配菜单");
        }

        // 3. 返回权限码列表
        return Optional.of(menuList).orElse(new ArrayList<>())
                .stream()
                .filter(item -> item != null && StringUtils.isNotEmpty(item.getCode()))
                .map(SysMenu::getCode)
                .collect(Collectors.toList());
    }

    /**
     * 返回一个账号所拥有的角色标识集合 (权限与角色可分开校验)
     */
    @Override
    public List<String> getRoleList(Object loginId, String loginType) {
        return new ArrayList<>();
    }
}
